package com.luo.d3s.ec.infrastructure.database.convertor;

import com.luo.d3s.core.util.IdGenUtils;
import com.luo.d3s.core.util.Optionals;
import com.luo.d3s.ec.application.dto.vo.OrderVo;
import com.luo.d3s.ec.domain.order.model.*;
import com.luo.d3s.ec.infrastructure.database.dataobject.OrderDo;
import com.luo.d3s.ec.infrastructure.database.dataobject.OrderGoodsDo;
import com.luo.d3s.share.model.BizId;
import com.luo.d3s.share.model.Count;
import com.luo.d3s.share.model.Price;
import org.springframework.util.CollectionUtils;

import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 订单对象转换器
 *
 * @author luohq
 * @date 2022-12-21 10:30
 */
public class OrderConvertor {

    public static OrderDo toOrderDo(Order order) {
        OrderDo orderDo = new OrderDo();
        orderDo.setId(Optionals.defaultNull(order.getId(), BizId::getValue));
        orderDo.setOrderStatus(Optionals.defaultNull(order.getOrderStatus(), OrderStatus::getValue));
        orderDo.setOrderPrice(Optionals.defaultNull(order.getOrderPrice(), Price::getValue));
        orderDo.setReceiveAddress(Optionals.defaultNull(order.getReceiveAddress(), ReceiveAddress::getValue));
        orderDo.setCreateTime(order.getCreateTime());
        orderDo.setPayTime(order.getPayTime());
        orderDo.setExpressCode(Optionals.defaultNull(order.getExpressCode(), ExpressCode::getValue));
        orderDo.setDeliverTime(order.getDeliverTime());
        orderDo.setCompleteTime(order.getCompleteTime());
        orderDo.setCancelTime(order.getCancelTime());
        orderDo.setUpdateTime(order.getUpdateTime());
        return orderDo;
    }

    public static OrderVo toOrderVo(OrderDo orderDo)  {
        OrderVo orderVo = new OrderVo();
        orderVo.setId(orderDo.getId());
        orderVo.setOrderStatus(orderVo.getOrderStatus());
        orderVo.setOrderPrice(orderDo.getOrderPrice());
        orderVo.setCreateTime(orderDo.getCreateTime());
        orderVo.setReceiveAddress(orderDo.getReceiveAddress());
        return orderVo;
    }

    public static Order toOrder(OrderDo orderDo, List<OrderGoodsDo> orderGoodsDoList) {
        Order order = new Order(
                BizId.of(orderDo.getId()),
                CollectionUtils.isEmpty(orderGoodsDoList)
                        ? Collections.emptyList() : orderGoodsDoList.stream().map(OrderConvertor::toOrderGoods).collect(Collectors.toList()),
                Price.of(orderDo.getOrderPrice()),
                ReceiveAddress.of(orderDo.getReceiveAddress()),
                OrderStatus.of(orderDo.getOrderStatus()),
                orderDo.getCreateTime(),
                orderDo.getPayTime(),
                Optionals.defaultNull(orderDo.getExpressCode(), ExpressCode::of),
                orderDo.getDeliverTime(),
                orderDo.getCompleteTime(),
                orderDo.getCancelTime(),
                orderDo.getUpdateTime()
        );
        return order;
    }

    public static OrderGoodsDo toOrderGoodsDo(Long orderId, OrderGoods orderGoods) {
        OrderGoodsDo orderGoodsDo = new OrderGoodsDo();
        orderGoodsDo.setId(IdGenUtils.nextDigitalId());
        orderGoodsDo.setGoodsId(Optionals.defaultNull(orderGoods.getGoodsId(), BizId::getValue));
        orderGoodsDo.setOrderId(orderId);
        orderGoodsDo.setGoodsCount(orderGoods.getGoodsCount().getValue());
        orderGoodsDo.setGoodsPrice(orderGoods.getGoodsPrice().getValue());
        orderGoodsDo.setGoodsSumPrice(orderGoods.getGoodsSumPrice().getValue());
        orderGoodsDo.setCreateTime(orderGoods.getCreateTime());
        orderGoodsDo.setUpdateTime(orderGoods.getUpdateTime());
        return orderGoodsDo;
    }

    public static OrderGoods toOrderGoods(OrderGoodsDo orderGoodsDo) {
        OrderGoods orderGoods = new OrderGoods(
                BizId.of(orderGoodsDo.getGoodsId()),
                Count.of(orderGoodsDo.getGoodsCount()),
                Price.of(orderGoodsDo.getGoodsPrice()),
                Price.of(orderGoodsDo.getGoodsSumPrice()),
                orderGoodsDo.getCreateTime(),
                orderGoodsDo.getUpdateTime()
        );
        return orderGoods;
    }
}
